//
// Created by yorkc on 2023/12/19.
//

#include <iostream>
#include "httpserver.h"
#include "../mongoose/mongoose.h"
#include "../sqllite/WSqlite.h"
#include "myfriends.h"
#include <nlohmann/json.hpp>
#include <sstream>

using namespace nlohmann;
using namespace std;
static int s_debug_level = MG_LL_INFO;
static const char *s_root_dir = ".";
static const char *s_listening_address = "http://0.0.0.0:8000";
static const char *s_enable_hexdump = "no";
static const char *s_ssi_pattern = "index.html";
constexpr char *content_type_json = "Content-Type: application/json\r\n";

// Handle interrupts, like Ctrl-C
static int s_signo;

static void signal_handler(int signo) {
    s_signo = signo;
}


/**
 * 连接事件处理
 * @param connection 连接
 * @param ev  事件
 * @param ev_data 事件数据
 * @param fn_data  函数参数
 */
static void connection_evt_handler(struct mg_connection *connection, int ev, void *ev_data, void *fn_data) {

    if (ev == MG_EV_HTTP_MSG) {
        struct mg_http_message *httpmsg = static_cast<mg_http_message *>(ev_data);
        mg_str *language = mg_http_get_header(httpmsg, "Language");
        cout << "http header language:" << language->ptr << endl;
#if 0
        //将消息转化(这步不用做了,ev_data已经是转化后的消息)
        struct mg_http_message msgrecv = {};
        mg_http_parse((char *) connection->recv.buf, connection->recv.len, &msgrecv);
        mg_str *language = mg_http_get_header(&msgrecv, "Language");
        cout<<"http language:"<<language->ptr<<endl;
#endif
        //MG_INFO(("method:%s,uri:%s,language:%s", httpmsg->method.ptr, httpmsg->uri.ptr,language->ptr));
        cout << "uri:" << httpmsg->uri.ptr << endl;
        if (mg_http_match_uri(httpmsg, "/api/**")) {
            cout << "this is uri:" << httpmsg->uri.ptr << endl;
            //char *jsonc = mg_mprintf("{%m:%d,%m:%m}", MG_ESC("status"), 1, MG_ESC("message"),MG_ESC("success"));
            //{"name":"haha","age":18,"b": [12, 2.30000],"a":1.23000}
            //char *buf = mg_mprintf("{%m:%m,%m:%d,%m: [%d, %f],%m:%f}", MG_ESC("name"),MG_ESC("haha"), MG_ESC("age"),18,MG_ESC("b"), 12,2.3,MG_ESC("a"),1.23);

            //查询数据库
            WSqlite ws;
            string dbpath = "/mnt/d/zhouyu.db";
            ws.Opendb(dbpath);
            vector<map<std::string, std::string>> results;
            string sql = "SELECT * from myfriends order by ID desc;";
            int queryData = ws.QueryData2(sql, results);
            if (queryData == SQLITE_OK && results.size() > 0) {
                results.at(0);
            }
            //数据转化为对象
            myfriends myfrienddb;
            // myfriends::db_to_objs(results);
            myfriends *db = myfrienddb.db_to_obj(results);
            cout << "db.id:" << db->getId() << endl;
            cout << "db.name:" << db->getName() << endl;
            cout << "db:age:" << db->getAge() << endl;
            cout << "db.major:" << db->getMajor() << endl;
            free(db);
            db = nullptr;

            json resp;
            resp["code"] = 1000;
            resp["message"] = "success";
            resp["data"] = nullptr;
            string jsonstr = resp.dump();
            mg_http_reply(connection, 200, content_type_json, "%s\n", jsonstr.c_str());
        } else {
            struct mg_http_serve_opts opts = {0};
            opts.root_dir = s_root_dir;
            opts.ssi_pattern = s_ssi_pattern;
            mg_http_serve_dir(connection, httpmsg, &opts);
        }
    }
}

static void usage(const char *prog) {
    fprintf(stderr,
            "Mongoose v.%s\n"
            "Usage: %s OPTIONS\n"
            "  -H yes|no - enable traffic hexdump, default: '%s'\n"
            "  -S PAT    - SSI filename pattern, default: '%s'\n"
            "  -d DIR    - directory to serve, default: '%s'\n"
            "  -l ADDR   - listening address, default: '%s'\n"
            "  -v LEVEL  - debug level, from 0 to 4, default: %d\n",
            MG_VERSION, prog, s_enable_hexdump, s_ssi_pattern, s_root_dir,
            s_listening_address, s_debug_level);
    exit(EXIT_FAILURE);
}

httpserver::httpserver() {

}

void httpserver::run() {
    /*
    int i;
    //Parse command-line flags
    for (i = 1; i < argc; i++) {
        if (strcmp(argv[i], "-d") == 0) {
            s_root_dir = argv[++i];
        } else if (strcmp(argv[i], "-H") == 0) {
            s_enable_hexdump = argv[++i];
        } else if (strcmp(argv[i], "-S") == 0) {
            s_ssi_pattern = argv[++i];
        } else if (strcmp(argv[i], "-l") == 0) {
            s_listening_address = argv[++i];
        } else if (strcmp(argv[i], "-v") == 0) {
            s_debug_level = atoi(argv[++i]);
        } else {
            usage(argv[0]);
        }
    }*/

    // Root directory must not contain double dots. Make it absolute
    // Do the conversion only if the root dir spec does not contain overrides
    char path[MG_PATH_MAX] = ".";
    if (strchr(s_root_dir, ',') == NULL) {
        realpath(s_root_dir, path);
        s_root_dir = path;
    }

    // Initialise stuff
    signal(SIGINT, signal_handler);
    signal(SIGTERM, signal_handler);

    //设置日志等级
    mg_log_set(s_debug_level);

    //初始化连接事件管理器
    struct mg_mgr mgr;
    mg_mgr_init(&mgr);

    //监听http连接
    struct mg_connection *connection;
    connection = mg_http_listen(&mgr, s_listening_address, connection_evt_handler, &mgr);
    if (connection == NULL) {
        MG_ERROR(("Cannot listen on %s. Use http://ADDR:PORT or :PORT", s_listening_address));
        exit(EXIT_FAILURE);
    }
    if (mg_casecmp(s_enable_hexdump, "yes") == 0) connection->is_hexdumping = 1;

    // Start infinite event loop
    MG_INFO(("Mongoose version : v%s", MG_VERSION));
    MG_INFO(("Listening on     : %s", s_listening_address));
    MG_INFO(("Web root         : [%s]", s_root_dir));
    while (s_signo == 0) mg_mgr_poll(&mgr, 1000);
    mg_mgr_free(&mgr);
    MG_INFO(("Exiting on signal %d", s_signo));
}
